package charts

import (
	"fmt"
	"regexp"
	"strconv"

	"github.com/golang/freetype/truetype"
	"github.com/wcharczuk/go-chart"
)

const (
	twenty = 20
	forty  = 40
	ten    = 10
	i64    = 64
)

var (
	reValue = regexp.MustCompile(`-{0,1}\d+.{0,1}\d*`)
	// nolint: lll
	reKey = regexp.MustCompile("[a-zA-Z\u4E00-\u62FF\u6300-\u77FF\u7800-\u8CFF\u8D00-\u9FFF]+( {0,1}[a-zA-Z\u4E00-\u62FF\u6300-\u77FF\u7800-\u8CFF\u8D00-\u9FFF]+)*")
)

// Simple 简单图表.
type Simple struct {
	Title string // 标题
	font  *truetype.Font
	x     []string
	y     []float64
}

// NewSimple 新建简单图表.
func NewSimple(title string, font *truetype.Font) *Simple {
	return &Simple{
		Title: title,
		font:  font,
		x:     []string{},
		y:     []float64{},
	}
}

// Add 增加数据.
func (s *Simple) Add(data ...string) {
	for _, d := range data {
		k, v := s.AddOne(d)
		s.y = append(s.y, v)
		s.x = append(s.x, k)
	}
}

func (s *Simple) AddOne(data string) (k string, v float64) {
	v, _ = strconv.ParseFloat(reValue.FindString(data), i64)
	k = reKey.FindString(data)

	return
}

// Bar 柱状图.
func (s *Simple) Bar() Render {
	bars := make([]chart.Value, len(s.y))

	for index, value := range s.y {
		if s.x[index] == "" {
			bars[index] = chart.Value{Value: value, Label: fmt.Sprintf("No. %d", index+1)}

			continue
		}

		bars[index] = chart.Value{Value: value, Label: s.x[index]}
	}

	char := chart.BarChart{
		Title: s.Title,
		Font:  s.font,
		Background: chart.Style{
			Padding: chart.Box{
				Top: forty,
			},
		},
		Bars: bars,
	}

	return char
}

// Graph 曲线图.
func (s *Simple) Graph() Render {
	data := make([]float64, len(s.y))

	for i := range s.y {
		data[i] = float64(i + 1)
	}

	char := chart.Chart{
		Title: s.Title,
		Font:  s.font,
		Background: chart.Style{
			Padding: chart.Box{
				Top:  twenty,
				Left: twenty,
			},
		},
		Series: []chart.Series{
			chart.ContinuousSeries{
				XValues: data,
				YValues: s.y,
			},
		},
	}

	return char
}

// Chart 创建图表.
func (s *Simple) Chart() Render {
	if len(s.y) < ten {
		return s.Bar()
	}

	return s.Graph()
}
